Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/jcomte23/Python_vanilla/llms.txt

Use this file to discover all available pages before exploring further.

Overview

This exercise builds a billing system that manages customer registration, product catalogs, invoice creation, and tax calculations. It demonstrates how to build a transaction-based system with running totals and final invoice generation.
Difficulty Level: AdvancedConcepts Covered: Tuples, dictionaries, invoice management, financial calculations, state management, multi-step workflows

What You’ll Learn

1

Immutable Product Catalog

Use tuples to create read-only product data that cannot be accidentally modified
2

Customer State Management

Track customer information throughout the session
3

Invoice Building

Accumulate line items into a complete invoice
4

Financial Calculations

Calculate line totals, subtotals, IVA (tax), and final totals

Complete Code

Here’s the full billing system implementation:
productos = (
    {
        "nombre": "pan",
        "valor": 1000
    },
    {
        "nombre": "galleta",
        "valor": 800
    },
    {
        "nombre": "arina",
        "valor": 1500
    }
)

documentoCliente = ""
nombreCliente = ""
apellidoCliente = ""
factura = []

while True:
    print()
    print("########")
    print("--MENU--")
    print("########")
    menu = """
    (1) Registar cliente  
    (2) Registrar un nuevo producto a la factura  
    (3) Listar productos actuales de la factura.   
    (4) Mostrar factura   
    (5) Apagar el programa
    """
    print(menu)

    opcionMenu = input("INGRESE LA OPCION=>")

    if opcionMenu == "1":
        if (documentoCliente == "" or nombreCliente == "" or apellidoCliente == ""):
            print("-------------------")
            print("Vamos a registrarte")
            documentoCliente = input("ingrese el # documento=>")
            nombreCliente = input("ingrese los nombres=>")
            apellidoCliente = input("ingrese los apellidos=>")
            print("-------------------")
            print("Datos registrados")
            print("DOC:", documentoCliente)
            print("NOMBRES:", nombreCliente)
            print("APELLIDOS:", apellidoCliente)
        else:
            print("-------------------")
            print("Ya hay un usuario registrado")
            print("DOC:", documentoCliente)
            print("NOMBRES:", nombreCliente)
            print("APELLIDOS:", apellidoCliente)
            print("Estas seguro que quieres actualizarlo?")
            respuesta = input("(1) si (2) no =>")
            if respuesta == "1":
                documentoCliente = input("ingrese el # documento=>")
                nombreCliente = input("ingrese los nombres=>")
                apellidoCliente = input("ingrese los apellidos=>")
                print("Datos registrados")
                print("DOC:", documentoCliente)
                print("NOMBRES:", nombreCliente)
                print("APELLIDOS:", apellidoCliente)
                print("Usuario actualizado")
    elif opcionMenu == "2":
        # aca listamos los productos disponibles
        indice = 0
        for producto in productos:
            print(f"[{indice}] {producto["nombre"]} {producto["valor"]}")
            indice += 1
        # en esta parte le pedimos al usuario que nos diga cual producto va agregar a la factura
        productoSeleccionado = int(input("ingrese el indice del producto que quieres agregar?=>"))
        cantidad = int(input("cuantas unidades vas a comprar?=>"))
        totalProducto = cantidad * productos[productoSeleccionado]["valor"]

        # creamos un nuevo diccionario para guardarlo en la factura
        nuevoProductoEnFactura = {
            "nombre": productos[productoSeleccionado]["nombre"],
            "valor": productos[productoSeleccionado]["valor"],
            "unidades": cantidad,
            "totalProducto": totalProducto
        }
        factura.append(nuevoProductoEnFactura)
        print("producto agregado a la factura")
    elif opcionMenu == "3":
        valorTotalFactura = 0
        for producto in factura:
            valorTotalFactura += producto["totalProducto"]

        print("FACTURA")
        print("Datos registrados")
        print("DOC:", documentoCliente)
        print("NOMBRES:", nombreCliente)
        print("APELLIDOS:", apellidoCliente)
        for producto in factura:
            print(f"{producto["nombre"]} {producto["valor"]}")


        print("--------------------")
        print(valorTotalFactura)

        cantidadProductos = len(factura)
        valorNeto = 0
        for producto in factura:
            valorNeto += producto["totalProducto"]
        impuestoIva = valorNeto * 0.19
        totalFactura = valorNeto + impuestoIva
        print("--------------------")
        print("productos en factura")
        print("--------------------")
        for producto in factura:
            print(f"{producto["nombre"]} {producto["valor"]} * {producto["unidades"]} = {producto["totalProducto"]}")
        print("--------------------")
    elif opcionMenu == "4":


    elif opcionMenu == "5":
        print("Feliz dia")
        break
    else:
        print("#############################")
        print("ingreste una opcion invalida")
        print("#############################")

Code Breakdown

Section 1: Product Catalog Using Tuple

productos = (
    {
        "nombre": "pan",
        "valor": 1000
    },
    {
        "nombre": "galleta",
        "valor": 800
    },
    {
        "nombre": "arina",
        "valor": 1500
    }
)
Why a Tuple? Using a tuple (immutable) instead of a list (mutable) prevents accidental modification of the product catalog. This is a good practice when you want to ensure certain data remains constant throughout the program.

Section 2: State Variables

documentoCliente = ""
nombreCliente = ""
apellidoCliente = ""
factura = []
These variables maintain state throughout the program:
  • Customer information (document, name, surname) stored as strings
  • Empty strings indicate no customer is registered
  • factura list accumulates invoice line items

Section 3: Customer Registration (Option 1)

if opcionMenu == "1":
    if (documentoCliente == "" or nombreCliente == "" or apellidoCliente == ""):
        # First registration
        print("Vamos a registrarte")
        documentoCliente = input("ingrese el # documento=>")
        nombreCliente = input("ingrese los nombres=>")
        apellidoCliente = input("ingrese los apellidos=>")
        print("Datos registrados")
    else:
        # Update existing customer
        print("Ya hay un usuario registrado")
        print("Estas seguro que quieres actualizarlo?")
        respuesta = input("(1) si (2) no =>")
        if respuesta == "1":
            # Update customer data
1

Check Existing Customer

Test if any customer field is empty using OR logic
2

Register or Update

Either collect new data or offer to update existing
3

Confirm Updates

Ask for confirmation before overwriting customer data

Section 4: Add Product to Invoice (Option 2)

elif opcionMenu == "2":
    # Display available products
    indice = 0
    for producto in productos:
        print(f"[{indice}] {producto["nombre"]} {producto["valor"]}")
        indice += 1
    
    # Get user selection
    productoSeleccionado = int(input("ingrese el indice del producto que quieres agregar?=>"))
    cantidad = int(input("cuantas unidades vas a comprar?=>"))
    totalProducto = cantidad * productos[productoSeleccionado]["valor"]

    # Create invoice line item
    nuevoProductoEnFactura = {
        "nombre": productos[productoSeleccionado]["nombre"],
        "valor": productos[productoSeleccionado]["valor"],
        "unidades": cantidad,
        "totalProducto": totalProducto
    }
    factura.append(nuevoProductoEnFactura)
Invoice Line Item Structure: Each item in the invoice contains:
  • nombre: Product name
  • valor: Unit price
  • unidades: Quantity purchased
  • totalProducto: Line total (unit price × quantity)

Section 5: Display Current Invoice (Option 3)

elif opcionMenu == "3":
    valorTotalFactura = 0
    for producto in factura:
        valorTotalFactura += producto["totalProducto"]

    print("FACTURA")
    print("Datos registrados")
    print("DOC:", documentoCliente)
    print("NOMBRES:", nombreCliente)
    print("APELLIDOS:", apellidoCliente)
    
    # Calculate totals
    valorNeto = 0
    for producto in factura:
        valorNeto += producto["totalProducto"]
    impuestoIva = valorNeto * 0.19
    totalFactura = valorNeto + impuestoIva
    
    # Display line items
    print("productos en factura")
    for producto in factura:
        print(f"{producto["nombre"]} {producto["valor"]} * {producto["unidades"]} = {producto["totalProducto"]}")
  1. Subtotal (valorNeto): Sum of all line item totals
  2. IVA (impuestoIva): 19% tax on subtotal
  3. Total (totalFactura): Subtotal + IVA
Formula: Total = Subtotal + (Subtotal × 0.19)

Section 6: Incomplete Feature (Option 4)

elif opcionMenu == "4":
    # Empty - not implemented
Missing Implementation: Option 4 (“Mostrar factura”) is declared in the menu but not implemented. This is likely meant to be the final invoice display, possibly with a different format than option 3.

How to Run

1

Save the File

Save the code in a file named billing_system.py
2

Run the Program

Execute from your terminal:
python billing_system.py
3

Follow the Workflow

  1. Register a customer (Option 1)
  2. Add products to invoice (Option 2, repeat as needed)
  3. View current invoice (Option 3)
  4. Exit (Option 5)

Example Session

########
--MENU--
########

(1) Registar cliente  
(2) Registrar un nuevo producto a la factura  
(3) Listar productos actuales de la factura.   
(4) Mostrar factura   
(5) Apagar el programa

INGRESE LA OPCION=>1
-------------------
Vamos a registrarte
ingrese el # documento=>12345678
ingrese los nombres=>Carlos
ingrese los apellidos=>Rodriguez
-------------------
Datos registrados
DOC: 12345678
NOMBRES: Carlos
APELLIDOS: Rodriguez

INGRESE LA OPCION=>2
[0] pan 1000
[1] galleta 800
[2] arina 1500
ingrese el indice del producto que quieres agregar?=>0
cuantas unidades vas a comprar?=>3
producto agregado a la factura

INGRESE LA OPCION=>2
[0] pan 1000
[1] galleta 800
[2] arina 1500
ingrese el indice del producto que quieres agregar?=>1
cuantas unidades vas a comprar?=>5
producto agregado a la factura

INGRESE LA OPCION=>3
FACTURA
Datos registrados
DOC: 12345678
NOMBRES: Carlos
APELLIDOS: Rodriguez
pan 1000
galleta 800
--------------------
7000
--------------------
productos en factura
--------------------
pan 1000 * 3 = 3000
galleta 800 * 5 = 4000
--------------------

Enhancement Ideas

  1. Complete Option 4: Implement a final formatted invoice display
  2. Payment Methods: Add cash, credit, debit payment options
  3. Change Calculation: Calculate change when customer pays with cash
  4. Invoice Numbering: Add sequential invoice numbers
  5. Date/Time Stamps: Record when each invoice was created
  6. Product Management: Add options to create/update/delete products
  7. Data Persistence: Save invoices and customers to files
  8. Receipt Printing: Generate printable receipt format
  9. Discount System: Apply percentage or fixed discounts
  10. Multiple Tax Rates: Support different tax rates for different products
  11. Update Quantities: Modify quantities after adding to invoice
  12. Remove Items: Delete line items from invoice
  13. Customer History: Track all invoices per customer

Common Issues and Solutions

Problem: User enters an invalid product index.Solution: Validate index range:
productoSeleccionado = int(input("ingrese el indice del producto que quieres agregar?=>"))
if 0 <= productoSeleccionado < len(productos):
    # proceed with adding product
else:
    print("Indice invalido")
Problem: Trying to view invoice before adding products.Solution: Check if invoice is empty:
if not factura:
    print("La factura esta vacia. Agrega productos primero.")
else:
    # display invoice
Issue: The code calculates valorTotalFactura and valorNeto separately but they’re the same.Optimization: Remove duplicate calculation:
subtotal = sum(producto["totalProducto"] for producto in factura)
iva = subtotal * 0.19
total = subtotal + iva

Real-World Applications

This billing system demonstrates concepts from:
  • Point of Sale (POS) Systems: Retail checkout systems
  • Invoice Management: Professional invoicing software
  • E-commerce Checkout: Online shopping cart completion
  • Restaurant Billing: Order management and bill generation

Key Concepts Demonstrated

Immutable Data Structures

productos = (...)  # Tuple - cannot be modified
Using tuples for the product catalog prevents accidental changes to prices or names.

State Management

documentoCliente = ""
factura = []
Maintaining state across multiple operations is essential for transaction-based systems.

Accumulator Pattern

subtotal = 0
for producto in factura:
    subtotal += producto["totalProducto"]
The accumulator pattern is fundamental for calculating running totals.

Confirmation Dialogs

print("Estas seguro que quieres actualizarlo?")
respuesta = input("(1) si (2) no =>")
if respuesta == "1":
    # proceed with update
Asking for confirmation prevents accidental data loss.

Key Takeaways

  • Tuples provide immutable data structures for constants like product catalogs
  • Empty strings can indicate “not set” state for customer data
  • Invoice line items should store all relevant details including calculated totals
  • Financial calculations must be precise and clearly documented
  • Multi-step workflows (register → add products → view invoice) are common in business applications
  • Confirmation dialogs improve user experience and prevent mistakes
  • Incomplete features (like option 4) should be noted and implemented
  • State management is crucial for maintaining customer and transaction data across operations